package com.meet.bizservice.impl;

import com.meet.persist.dao.ActivityDao;
import com.meet.persist.dao.ActivityParticipantDao;
import com.meet.api.dto.request.MeetActivityRequestDTO;
import com.meet.api.dto.response.MeetActivityCreatorResponseDTO;
import com.meet.api.dto.response.MeetActivityLocationResponseDTO;
import com.meet.api.dto.response.MeetActivityResponseDTO;
import com.meet.api.dto.response.MeetActivityTimeResponseDTO;
import com.meet.persist.entity.Activity;
import com.meet.exception.BusinessException;
import com.meet.bizservice.ActivityService;
import com.meet.util.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

@Service
public class ActivityServiceImpl implements ActivityService {

    private static final Logger logger = LoggerFactory.getLogger(ActivityServiceImpl.class);

    @Autowired
    private ActivityDao activityDao;

    @Autowired
    private ActivityParticipantDao activityParticipantDao;

    @Override
    public Result<List<MeetActivityResponseDTO>> getActivities(int page, int limit, String location,
                                                               String category, String timeFilter, String keyword) {

        try {
            // 计算分页偏移量
            int offset = (page - 1) * limit;

            // 查询活动列表
            List<Activity> activities = activityDao.findActivities(offset, limit, location, category, timeFilter, keyword);

            // 转换为DTO列表
            List<MeetActivityResponseDTO> activityDTOs = activities.stream()
                    .map(this::convertToResponseDTO)
                    .collect(Collectors.toList());

            // 查询总数量
            int total = activityDao.countActivities(location, category, timeFilter, keyword);

            // 计算总页数
            int totalPages = (int) Math.ceil((double) total / limit);

            logger.info("Successfully retrieved {} activities for page {}", activityDTOs.size(), page);
            return Result.success(activityDTOs);
        } catch (Exception e) {
            logger.error("Error retrieving activities", e);
            throw new BusinessException("Failed to retrieve activities");
        }
    }

    @Override
    public Result<MeetActivityResponseDTO> getActivityDetail(String activityId) {

        try {
            Activity activity = activityDao.findById(activityId);

            if (activity == null) {
                return Result.error(404, "Activity not found");
            }

            MeetActivityResponseDTO activityDTO = convertToResponseDTO(activity);
            // 对于活动详情，需要额外设置评论列表（这里简化处理）
            // activityDTO.setActivityCommentDTOS(null); // 实际应用中应该查询评论数据

            logger.info("Successfully retrieved activity detail for ID: {}", activityId);
            return Result.success(activityDTO);
        } catch (Exception e) {
            logger.error("Error retrieving activity detail for ID: {}", activityId, e);
            throw new BusinessException("Failed to retrieve activity detail");
        }
    }

    @Override
    public Result<String> createActivity(MeetActivityRequestDTO activityDTO) {

        try {
            // 生成活动ID
            String activityId = UUID.randomUUID().toString().replace("-", "");
            Activity activity = convertToEntity(activityDTO);
            activity.setActivityId(activityId);

            // 设置默认值
            if (activity.getStatus() == null) {
                activity.setStatus("upcoming");
            }

            if (activity.getParticipantsCount() == null) {
                activity.setParticipantsCount(0);
            }

            // 插入活动
            if (activityDao.insert(activity)) {
                logger.info("Successfully created activity with ID: {}", activityId);
                return Result.success(activityId);
            } else {
                logger.error("Failed to create activity");
                return Result.error("Failed to create activity");
            }
        } catch (Exception e) {
            logger.error("Error creating activity", e);
            throw new BusinessException("Failed to create activity");
        }
    }

    @Override
    public Result<Boolean> registerForActivity(String activityId, String userId) {

        try {
            // 检查活动是否存在
            Activity activity = activityDao.findById(activityId);
            if (activity == null) {
                return Result.error(404, "Activity not found");
            }

            // 检查用户是否已注册
            if (activityParticipantDao.isRegistered(activityId, userId)) {
                return Result.error("User already registered for this activity");
            }

            // 注册用户
            if (activityParticipantDao.register(activityId, userId)) {
                // 更新活动参与者数量
                activity.setParticipantsCount(activity.getParticipantsCount() + 1);
                activityDao.update(activity);

                logger.info("User {} registered for activity {}", userId, activityId);
                return Result.success(true);
            } else {
                logger.error("Failed to register user {} for activity {}", userId, activityId);
                return Result.error("Failed to register for activity");
            }
        } catch (Exception e) {
            logger.error("Error registering user {} for activity {}", userId, activityId, e);
            throw new BusinessException("Failed to register for activity");
        }
    }

    @Override
    public Result<Boolean> cancelRegistration(String activityId, String userId) {

        try {
            // 检查活动是否存在
            Activity activity = activityDao.findById(activityId);
            if (activity == null) {
                return Result.error(404, "Activity not found");
            }

            // 取消注册
            if (activityParticipantDao.cancelRegistration(activityId, userId)) {
                // 更新活动参与者数量
                if (activity.getParticipantsCount() > 0) {
                    activity.setParticipantsCount(activity.getParticipantsCount() - 1);
                    activityDao.update(activity);
                }

                logger.info("User {} cancelled registration for activity {}", userId, activityId);
                return Result.success(true);
            } else {
                logger.error("Failed to cancel registration for user {} from activity {}", userId, activityId);
                return Result.error("Failed to cancel registration");
            }
        } catch (Exception e) {
            logger.error("Error cancelling registration for user {} from activity {}", userId, activityId, e);
            throw new BusinessException("Failed to cancel registration");
        }
    }

    private MeetActivityResponseDTO convertToResponseDTO(Activity activity) {

        if (activity == null) {
            return null;
        }

        MeetActivityResponseDTO dto = new MeetActivityResponseDTO();
        dto.setActivityId(activity.getActivityId());
        dto.setTitle(activity.getTitle());
        dto.setDescription(activity.getDescription());
        dto.setCoverUrl(activity.getCoverUrl());

        // 创建Location嵌套对象
        MeetActivityLocationResponseDTO activityLocationDTO = new MeetActivityLocationResponseDTO();
        activityLocationDTO.setName(activity.getLocationName());
        activityLocationDTO.setAddress(activity.getLocationAddress());
        dto.setActivityLocation(activityLocationDTO);

        // 创建Time嵌套对象
        MeetActivityTimeResponseDTO activityTimeDTO = new MeetActivityTimeResponseDTO();
        activityTimeDTO.setStartTime(activity.getStartTime());
        activityTimeDTO.setEndTime(activity.getEndTime());
        dto.setActivityTime(activityTimeDTO);

        // 设置分类为字符串数组
        if (activity.getCategory() != null) {
            dto.setCategory(java.util.Arrays.asList(activity.getCategory().split(",")));
        }

        dto.setTemperatureTag(activity.getTemperatureTag());
        dto.setMaxParticipants(activity.getMaxParticipants());
        dto.setFee(activity.getFee());  // 添加费用字段

        // 创建Creator嵌套对象
        MeetActivityCreatorResponseDTO activityCreatorDTO = new MeetActivityCreatorResponseDTO();
        activityCreatorDTO.setUserId(activity.getCreatorId());
        // 这里需要额外查询用户名，暂时设置为默认值
        activityCreatorDTO.setUsername("未知用户");
        dto.setActivityCreator(activityCreatorDTO);

        dto.setStatus(activity.getStatus());
        // 添加isRegistered字段（需要根据当前用户状态设置）
        dto.setIsRegistered(false);  // 默认为false，实际应用中需要根据用户ID判断

        dto.setParticipantsCount(activity.getParticipantsCount());
        dto.setCreatedAt(activity.getCreatedAt());
        dto.setUpdatedAt(activity.getUpdatedAt());

        return dto;
    }

    private Activity convertToEntity(MeetActivityRequestDTO dto) {

        if (dto == null) {
            return null;
        }

        Activity activity = new Activity();
        activity.setActivityId(dto.getActivityId());
        activity.setTitle(dto.getTitle());
        activity.setDescription(dto.getDescription());
        activity.setCoverUrl(dto.getCoverUrl());

        // 从嵌套对象中提取数据
        if (dto.getActivityLocation() != null) {
            activity.setLocationName(dto.getActivityLocation().getName());
            activity.setLocationAddress(dto.getActivityLocation().getAddress());
        }

        if (dto.getActivityTime() != null) {
            activity.setStartTime(dto.getActivityTime().getStartTime());
            activity.setEndTime(dto.getActivityTime().getEndTime());
        }

        // 将分类列表转换为字符串
        if (dto.getCategory() != null && !dto.getCategory().isEmpty()) {
            activity.setCategory(String.join(",", dto.getCategory()));
        }

        activity.setTemperatureTag(dto.getTemperatureTag());
        activity.setMaxParticipants(dto.getMaxParticipants());
        activity.setFee(dto.getFee());  // 添加费用字段

        // 从嵌套对象中提取创建者ID
        if (dto.getActivityCreator() != null) {
            activity.setCreatorId(dto.getActivityCreator().getUserId());
        }

        activity.setStatus(dto.getStatus());
        activity.setParticipantsCount(dto.getParticipantsCount());
        activity.setCreatedAt(dto.getCreatedAt());
        activity.setUpdatedAt(dto.getUpdatedAt());

        return activity;
    }

}
